//===========================================================================================================================
// Cuberry - http://www.cuberry.net
// Copyright (c) 2012
// by Peacequare® - Amir Moussa
//===========================================================================================================================
// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation, either version 3 of the License, or any later version.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// This program is distributed in the hope that it will be useful.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//===========================================================================================================================

using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.Unity;
using P2.Cuberry.Framework.Helper;
using P2.Cuberry.Modules.SimpleAccounting.FiCheque.Services;
using Microsoft.Practices.Prism.Events;
using System.Linq;

namespace P2.Cuberry.Modules.SimpleAccounting.FiCheque
{
    public class FiChequeModule : IModule, IShowableModule
    {
        private readonly IUnityContainer container;
        private readonly IRegionManager regionManager;
        private readonly IEventAggregator eventAggregator;

        public string ModuleName
        {
            get
            { return Properties.Settings.Default.ModuleName; }
        }


        public FiChequeModule(IUnityContainer container, IRegionManager regionManager, IEventAggregator eventAggregator)
        {
            this.container = container;
            this.regionManager = regionManager;
            this.eventAggregator = eventAggregator;
            ModuleRepository.Modules.Add(this.ModuleName, this);
        }


        public void Initialize()
        {
            this.RegisterViewsAndServices();
            this.RegisterViewsWithRegions();

            var checkEvent = eventAggregator.GetEvent<P2Event>();
            checkEvent.Subscribe(P2EventHandler);
        }

        void P2EventHandler(P2EventParameter parameter) 
        {
            // event handler for cross-module event calls
            if (parameter != null)
            {
                if (parameter.Name == "FiTransactionItem_Update_PreValidate")
                {
                    // pre-validate event call - it is invoked by FiTransaction module before the FiTransactionItemID is being deleted or updated
                    IFiChequeService service = container.Resolve<IFiChequeService>();
                    BusinessEntities.FiCheque cheque = service.RetrieveChequeByTransactionItemID(int.Parse(parameter.Parameters["FiTransactionItemID"]));
                    if (cheque != null)
                    {
                        // if cheque for given FiTransactionItemID exists, verify access rights
                        var controlRights = cheque.GetControls(Properties.Settings.Default.ModuleName, "FiChequesDetailsView");
                        P2.Cuberry.Framework.Security.User.ControlRight controlRight;
                        if (controlRights.TryGetValue("FiChequeSaveBtn", out controlRight) && controlRight.IsActive)
                            // OK - user has edit acccess right
                            parameter.Messages.Add(new P2TransactionMessage(P2ValidationStatus.green, "Cheque update OK"));
                        else
                            // access denied
                            parameter.Messages.Add(new P2TransactionMessage(P2ValidationStatus.red, "Cheque update denied"));
                    }
                    

                }
                if (parameter.Name == "FiTransactionItem_Update")
                {
                    // FiTransactionItemId deleted or updated
                    IFiChequeService service = container.Resolve<IFiChequeService>();
                    var originalFiTransactionItemID = int.Parse(parameter.Parameters["FiTransactionItemID"]);
                    BusinessEntities.FiCheque cheque = service.RetrieveChequeByTransactionItemID(originalFiTransactionItemID);
                    if (cheque != null)
                    {
                        // if cheque is found
                        if (parameter.Parameters.ContainsKey("FiTransactionItemIDNew"))
                        {
                            // FiTransactionItemIDNew provided - update (switch)
                            cheque.FiTransactionID = int.Parse(parameter.Parameters["FiTransactionItemIDNew"]);
                        } else {
                            // FITransactionItem deleted
                            cheque.FiTransactionID  = null;
                            cheque.StatusID = 170502; // cancel when transaction item ID deleted
                        }
                        cheque.InsertAndUpdate(parameter.Messages, false);
                        if (originalFiTransactionItemID < -1)
                        {
                            // remove from temporary storage
                            var removeItem = BusinessEntities.FiCheque.TemporaryStorage.FirstOrDefault(it => it.FiTransactionID == originalFiTransactionItemID);
                            if (removeItem != null)
                                BusinessEntities.FiCheque.TemporaryStorage.Remove(removeItem);
                        }
                    }
                    
                }

            }
        }
 


        public void Show()
        {
            FiChequesPresenter presenter = this.container.Resolve<FiChequesPresenter>();
            FiChequesFindPresenter findPresenter = this.container.Resolve<FiChequesFindPresenter>();            

            IRegion mainRegion = this.regionManager.Regions[RegionNames.MainRegion];
            IRegion findRegion = this.regionManager.Regions[RegionNames.FindRegion];
                        
            //ChequesFindView findView = this.container.Resolve<ChequesFindView>();
            mainRegion.Add(presenter.View, "ChequesView");
            findRegion.Add(findPresenter.View, "ChequesFindView");
        }


        public void Hide()
        {
            FiChequesPresenter presenter = this.container.Resolve<FiChequesPresenter>();

            IRegion mainRegion = this.regionManager.Regions[RegionNames.MainRegion];
            IRegion findRegion = this.regionManager.Regions[RegionNames.FindRegion];
            try
            {
                mainRegion.Remove(mainRegion.GetView("ChequesView"));
                findRegion.Remove(findRegion.GetView("ChequesFindView"));
            }
            catch (System.Exception)
            {
            }
        }


        protected void RegisterViewsAndServices()
        {
            // TODO: should be a singleton;
            this.container.RegisterType<IFiChequeService, FiChequeService>();
            this.container.RegisterType<IFiChequesView, FiChequesView>();

            this.container.RegisterType<IFiChequesListView, FiChequesListView>();
            this.container.RegisterType<IFiChequesListPresenter, FiChequesListPresenter>();

            this.container.RegisterType<IFiChequesFindView, FiChequesFindView>();
            this.container.RegisterType<IFiChequesDetailsView, FiChequesDetailsView>();
            this.container.RegisterType<IFiChequesTransactionButtonView, FiChequesTransactionButtonView>();
            this.container.RegisterType<FiChequesDetailsPresentationModel, FiChequesDetailsPresentationModel>();

        }

        private void RegisterViewsWithRegions()
        {
            // Method 1: 
            this.regionManager.RegisterViewWithRegion(RegionNames.FiTransactionItemDetailMenu,
                    () => this.container.Resolve<IFiChequesTransactionButtonView>());

        }
 

    }
}